import { SEALS } from '../../../config/static';

import domtoimage from 'dom-to-image';

import util from '@/libs/util';
import Cookies from 'js-cookie';
import CONSTANTS from '@/config/constants';
import getDate from '@/util/getDate.js';

const DEFAULT_SEAL_WIDTH = 200;
const ATTRACT_DISTANCE = 10 // 吸附距离，10像素

export default {
    props: ['makeTemplate', 'activeSpriteIndex'],
    data() {
        return {
            render: {
                bgOriginWidth: 0,
                bgOriginHeight: 0,
                bgScale: 1,

                previewContainerWidth: 0,
                previewContainerHeight: 0
            },
            drag: {
                draggingIndex: -1,
                mouseDownX: 0,
                mouseDownY: 0,

                mouseDownSpriteX: 0,
                mouseDownSpriteY: 0,

                mouseDownSpriteWidth: 0,
                mouseDownSpriteHeight: 0,

                resizer: '', // nw | ne | sw | se
                spriteRatio: 0
            },
            pointMarks: {
                x: [],
                y: []
            },
            attractedX: -1,
            attractedY: -1,

            $image: null
        };
    },
    mounted() {
        this.$previewContainer = this.$el.querySelector('.make-preview');
        this.$bgEl = this.$el.querySelector('.bg-image');
        this.$image = this.$el.querySelector('.image-edit')

        /* this.$bgEl.addEventListener('load', (e) => {
            this.$nextTick(() => {
                console.log(e.target)
                this.fitBg();
            });
        }); */
        // this.applyContainerSize();

        // window.addEventListener('resize', this.applyContainerSize);
    },
    methods: {
        getSpriteStyle(sprite) {
            let style = {
                transform: `translateX(${sprite.x}px) translateY(${sprite.y}px)`
            };
            if (sprite.type === 'picture') {
                style.width = `${sprite.width}px`;
                style.height = `${sprite.height}px`
            }
            return style;
        },
        spriteMouseDown(e, i) {
            this.activateSprite(i)

            this.drag.draggingIndex = i;
            this.drag.mouseDownX = e.clientX;
            this.drag.mouseDownY = e.clientY;

            let currSprite = this.makeTemplate.sprites[this.drag.draggingIndex];

            this.applyPointMarks(currSprite)

            let targetEl = e.path[0],
                targetElClassList = targetEl.className.split(/\s+/);
            if (targetElClassList.indexOf('resizer') > -1) {
                // 调整大小
                this.drag.resizer = ['nw', 'ne', 'sw', 'se'].find(item => {
                    return targetElClassList.indexOf(item) > -1;
                });

                this.drag.mouseDownSpriteWidth = currSprite.width;
                this.drag.mouseDownSpriteHeight = currSprite.height;

                this.spriteRatio = currSprite.width / currSprite.height;
            } else {
                // 拖拽位置
                this.drag.resizer = '';
            }

            this.drag.mouseDownSpriteX = currSprite.x;
            this.drag.mouseDownSpriteY = currSprite.y;

            document.addEventListener('mousemove', this.spriteMouseMove);
            document.addEventListener('mouseup', this.spriteMouseUp);
        },
        spriteMouseMove(e) {
            let currSprite = this.makeTemplate.sprites[this.drag.draggingIndex],
                offsetX = (e.clientX - this.drag.mouseDownX) / this.render.bgScale,
                offsetY = (e.clientY - this.drag.mouseDownY) / this.render.bgScale,

                mouseX = this.drag.mouseDownSpriteX + offsetX,
                mouseY = this.drag.mouseDownSpriteY + offsetY

            if (this.drag.resizer === '') {
                // 调整位置

                // 判断吸附
                const attractedXL = this.pointMarks.x.find(p => Math.abs(p - mouseX) * this.render.bgScale <= ATTRACT_DISTANCE),
                    attractedYT = this.pointMarks.y.find(p => Math.abs(p - mouseY) * this.render.bgScale <= ATTRACT_DISTANCE),
                    attractedXR = attractedXL ? -1 : this.pointMarks.x.find(p => Math.abs(p - (mouseX + currSprite.width)) * this.render.bgScale <= ATTRACT_DISTANCE),
                    attractedYB = attractedYT ? -1 : this.pointMarks.y.find(p => Math.abs(p - (mouseY + currSprite.height)) * this.render.bgScale <= ATTRACT_DISTANCE)

                if (attractedXL) {
                    this.attractedX = attractedXL
                    offsetX = attractedXL - this.drag.mouseDownSpriteX
                } else {
                    if (attractedXR) {
                        this.attractedX = attractedXR
                        offsetX = attractedXR - this.drag.mouseDownSpriteX - currSprite.width
                    } else {
                        this.attractedX = -1
                    }
                }
                if (attractedYT) {
                    this.attractedY = attractedYT
                    offsetY = attractedYT - this.drag.mouseDownSpriteY
                } else {
                    if (attractedYB) {
                        this.attractedY = attractedYB
                        offsetY = attractedYB - this.drag.mouseDownSpriteY - currSprite.height
                    } else {
                        this.attractedY = -1
                    }
                }

                currSprite.x = this.drag.mouseDownSpriteX + offsetX
                currSprite.y = this.drag.mouseDownSpriteY + offsetY
            } else {
                // 调整大小

                /* let shiftX = currSprite.x, shiftY = currSprite.y
                if (['ne', 'se'].indexOf(this.drag.resizer) > -1) {
                    shiftX += currSprite.width
                }
                if (['se', 'sw'].indexOf(this.drag.resizer) > -1) {
                    shiftY += currSprite.height
                }

                const attractedX = this.pointMarks.x.find(p => Math.abs(p - shiftX) * this.render.bgScale <= ATTRACT_DISTANCE),
                    attractedY = this.pointMarks.y.find(p => Math.abs(p - shiftY) * this.render.bgScale <= ATTRACT_DISTANCE)

                if (attractedX) {
                    this.attractedX = attractedX
                    offsetX = attractedX * this.render.bgScale - this.drag.mouseDownX
                } else {
                    this.attractedX = -1
                }
                if (attractedY) {
                    this.attractedY = attractedY
                    offsetY = attractedY * this.render.bgScale - this.drag.mouseDownY
                } else {
                    this.attractedY = -1
                } */

                let deltaX = 0, deltaY = 0;
                if (Math.abs(offsetX) > Math.abs(offsetY)) {
                    deltaX = offsetX
                    deltaY = offsetX / this.spriteRatio

                    if (['ne', 'sw'].indexOf(this.drag.resizer) > -1) {
                        deltaY = -deltaY;
                    }
                } else {
                    deltaY = offsetY
                    deltaX = offsetY * this.spriteRatio

                    if (['ne', 'sw'].indexOf(this.drag.resizer) > -1) {
                        deltaX = -deltaX;
                    }
                }

                // deltaX /= this.render.bgScale
                // deltaY /= this.render.bgScale

                switch (this.drag.resizer) {
                    case 'nw':
                        currSprite.x = this.drag.mouseDownSpriteX + deltaX;
                        currSprite.y = this.drag.mouseDownSpriteY + deltaY;
                        currSprite.width = this.drag.mouseDownSpriteWidth - deltaX;
                        currSprite.height = this.drag.mouseDownSpriteHeight - deltaY;
                        break;
                    case 'ne':
                        // currSprite.x = this.drag.mouseDownSpriteX + deltaX;
                        currSprite.y = this.drag.mouseDownSpriteY + deltaY;
                        currSprite.width = this.drag.mouseDownSpriteWidth + deltaX;
                        currSprite.height = this.drag.mouseDownSpriteHeight - deltaY;
                        break;
                    case 'sw':
                        currSprite.x = this.drag.mouseDownSpriteX + deltaX;
                        // currSprite.y = this.drag.mouseDownSpriteY + deltaY;
                        currSprite.width = this.drag.mouseDownSpriteWidth - deltaX;
                        currSprite.height = this.drag.mouseDownSpriteHeight + deltaY;
                        break;
                    case 'se':
                        // currSprite.x = this.drag.mouseDownSpriteX + deltaX;
                        // currSprite.y = this.drag.mouseDownSpriteY + deltaY;
                        currSprite.width = this.drag.mouseDownSpriteWidth + deltaX;
                        currSprite.height = this.drag.mouseDownSpriteHeight + deltaY;
                        break;
                }
            }
        },
        spriteMouseUp(e) {
            document.removeEventListener('mousemove', this.spriteMouseMove)
            document.removeEventListener('mouseup', this.spriteMouseUp)

            this.attractedX = -1
            this.attractedY = -1
        },
        activateSprite(i) {
            // this.activeSpriteIndex = i
            this.$emit('activate-sprite', i)
        },
        applyContainerSize(width, height) {
            this.render.previewContainerWidth = width;
            this.render.previewContainerHeight = height;

            this.fitBg()
        },
        fitBg() {
            if (this.render.previewContainerWidth / this.render.previewContainerHeight > this.render.bgOriginWidth / this.render.bgOriginHeight) {
                this.render.bgScale = this.render.previewContainerHeight / this.render.bgOriginHeight
            } else {
                this.render.bgScale = this.render.previewContainerWidth / this.render.bgOriginWidth
            }
        },
        /**
         * 更新所有元素坐标点信息（吸附用）
         */
        applyPointMarks(ignoredSprite) {
            const xPoints = [],
                yPoints = []
            this.makeTemplate.sprites.forEach(sprite => {
                if (sprite !== ignoredSprite) {
                    xPoints.push(sprite.x, sprite.x + sprite.width)
                    yPoints.push(sprite.y, sprite.y + sprite.height)
                }
            })
            this.pointMarks.x = xPoints
            this.pointMarks.y = yPoints
        },
        /**
         * 生成图片时还原缩放比例
         */
        capture() {
            const scale = this.render.bgScale
            this.render.bgScale = 1
            return function (_scale) {
                this.render.bgScale = _scale
            }.bind(this, scale)
        },
        /**
         * 获取sprite尺寸
         * @param {number} i 
         */
        measureSpriteSize(i) {
            const sprite = this.$el.querySelector(`#sprite_${i}`),
                spriteRect = { width: sprite.width, height: sprite.height }
            if (sprite) {
                const rect = sprite.getBoundingClientRect()
                spriteRect.width = rect.width / this.render.bgScale
                spriteRect.height = rect.height / this.render.bgScale
            }
            return spriteRect
        },
        updateSpriteTextByName(name, text) {
            this.updateSpriteText(this.makeTemplate.sprites.findIndex(sprite => sprite.name === name), text)
        },
        updateSpriteText(i, text) {
            const sprite = this.makeTemplate.sprites[i]
            if (sprite.align !== 'left') {
                const x = sprite.x,
                    width = sprite.width
                sprite.content = text
                this.$nextTick(() => {
                    // const { width, height } = this.measureSpriteSize(this.activeSpriteIndex)
                    Object.assign(this.makeTemplate.sprites[i], this.measureSpriteSize(i))
                    if (sprite.align === 'center') {
                        sprite.x -= (sprite.width - width) / 2
                    } else if (sprite.align === 'right') {
                        sprite.x -= (sprite.width - width)
                    }
                })
            } else {
                sprite.content = text
                this.$nextTick(() => {
                    Object.assign(this.makeTemplate.sprites[i], this.measureSpriteSize(i))
                })
            }
        },
        stripContent(content) {
            return content.replace(/\$@\$/g, '')
        }
    },
    computed: {
        previewContainerStyle() {
            /* return {
                width: `${this.render.bgOriginWidth * this.render.bgScale}px`,
                height: `${this.render.bgOriginHeight * this.render.bgScale}px`
            }; */
            return {
                width: `${this.render.previewContainerWidth}px`
            }
        },
        imageContainerStyle() {
            return {
                width: `${this.render.bgOriginWidth}px`,
                height: `${this.render.bgOriginHeight}px`,
                transform: `scale(${this.render.bgScale})`
            }
        },
        retrieveScaleStyle() {
            return {
                transform: `scale(${1 / this.render.bgScale})`
            }
        }
    },
    watch: {
        'makeTemplate.backgroundUrl': function (n, o) {
            console.log(n)
            let newImg = new Image();
            newImg.onload = () => {
                this.render.bgOriginWidth = newImg.width;
                this.render.bgOriginHeight = newImg.height;
                this.fitBg()
            };
            newImg.src = n;
        },
        'makeTemplate.sprites': {
            handler: function (n, o) {
                // this.applyPointMarks()
            },
            deep: true
        }
    },
    beforeDestroy() {
        // window.removeEventListener('resize', this.applyContainerSize);
    }
};